package com.maint.m

import android.app.Activity
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.widget.Toast
import com.google.gson.Gson
import java.lang.ref.WeakReference

/**
 * WebSocket 消息类型枚举
 */
enum class WebSocketMessageType {
    UNKNOWN,
    CONNECTED,
    TICKET_UPDATE,
    OPERATION_STATUS,
    ERROR
}

/**
 * 简化的 WebSocket 消息处理器接口
 */
interface SimpleWebSocketHandler {
    fun onMessageReceived(type: WebSocketMessageType, message: String)
    fun onConnectionChanged(connected: Boolean)
    fun onError(errorMsg: String)
}

/**
 * WebSocket 服务类，提供高级封装，简化使用
 */
class WebSocketService private constructor() : WebSocketMessageListener {
    private val TAG = "WebSocketService"
    private val webSocketManager = WebSocketManager.getInstance()
    private val gson = Gson()
    private val handlers = mutableListOf<HandlerWithContext>()
    private val mainHandler = Handler(Looper.getMainLooper())
    private var autoConnect = true
    
    // 内部类，用于持有上下文的弱引用
    private class HandlerWithContext(
        val handler: SimpleWebSocketHandler,
        val context: WeakReference<Any>?
    )
    
    companion object {
        @Volatile
        private var INSTANCE: WebSocketService? = null
        
        fun getInstance(): WebSocketService {
            return INSTANCE ?: synchronized(this) {
                INSTANCE ?: WebSocketService().also { INSTANCE = it }
            }
        }
    }
    
    init {
        // 注册自身到 WebSocketManager
        webSocketManager.registerMessageListener(this)
    }
    
    /**
     * 连接 WebSocket
     */
    fun connect() {
        if (!webSocketManager.isConnected()) {
            Log.i("WebSocketService", "正在连接 WebSocket...")
            webSocketManager.connect()
        }
    }
    
    /**
     * 断开 WebSocket 连接
     */
    fun disconnect() {
        webSocketManager.disconnect()
    }
    
    /**
     * 发送 WebSocket 消息
     * @param message 要发送的消息内容
     * @param showToast 是否显示发送结果的 Toast
     * @param context 上下文，用于显示 Toast
     * @return 是否发送成功
     */
    fun sendMessage(message: String, showToast: Boolean = false, context: Context? = null): Boolean {
        // 如果未连接且启用了自动连接，则先连接
        if (!webSocketManager.isConnected() && autoConnect) {
            connect()
            // 延迟发送，等待连接建立
            mainHandler.postDelayed({
                doSendMessage(message, showToast, context)
            }, 1000)
            return false
        }
        return doSendMessage(message, showToast, context)
    }
    
    /**
     * 发送结构化消息
     * @param business 业务类型
     * @param data 数据内容
     * @param showToast 是否显示发送结果的 Toast
     * @param context 上下文，用于显示 Toast
     * @return 是否发送成功
     */
    fun sendStructuredMessage(business: Int, data: Any? = null, showToast: Boolean = false, context: Context? = null): Boolean {
        val messageMap = mutableMapOf("business" to business.toString())
        if (data != null) {
            messageMap["data"] = data.toString()
        }
        val message = gson.toJson(messageMap)
        return sendMessage(message, showToast, context)
    }
    
    /**
     * 注册消息处理器
     * @param handler 消息处理器
     * @param context 上下文对象，用于引用管理
     */
    fun registerHandler(handler: SimpleWebSocketHandler, context: Any? = null) {
        // 如果已经连接，立即通知处理器
        if (webSocketManager.isConnected()) {
            mainHandler.post {
                handler.onConnectionChanged(true)
            }
        } else {
            connect()
        }

        val contextRef = context?.let { WeakReference(it) }
        handlers.add(HandlerWithContext(handler, contextRef))
    }
    
    /**
     * 注销消息处理器
     * @param handler 要注销的消息处理器
     */
    fun unregisterHandler(handler: SimpleWebSocketHandler) {
        handlers.removeAll { it.handler === handler }
    }
    
    /**
     * 设置是否自动连接
     */
    fun setAutoConnect(enable: Boolean) {
        this.autoConnect = enable
    }
    
    /**
     * 检查是否已连接
     */
    fun isConnected(): Boolean {
        return webSocketManager.isConnected()
    }
    
    /**
     * 内部发送消息方法
     */
    private fun doSendMessage(message: String, showToast: Boolean, context: Any?): Boolean {
        val success = webSocketManager.sendMessage(message)
        
        // 替换Toast为Log，记录消息发送状态
        Log.d(TAG, "消息发送${if (success) "成功" else "失败，请重试"}: $message")
        
        return success
    }
    
    /**
     * 解析消息类型
     */
    private fun parseMessageType(message: String): WebSocketMessageType {
        return try {
            when {
                message.contains("connected") -> WebSocketMessageType.CONNECTED
                message.contains("\"business\":0") && message.contains("\"data\":\"ok\"") -> WebSocketMessageType.TICKET_UPDATE
                message.contains("status") -> WebSocketMessageType.OPERATION_STATUS
                message.contains("error") || message.contains("fail") -> WebSocketMessageType.ERROR
                else -> WebSocketMessageType.UNKNOWN
            }
        } catch (e: Exception) {
            WebSocketMessageType.UNKNOWN
        }
    }
    
    /**
     * 清理无效的处理器（上下文已被回收的）
     */
    private fun cleanInvalidHandlers() {
        handlers.removeAll { it.context?.get() == null }
    }
    
    /**
     * 通知所有处理器
     */
    private fun notifyHandlers(action: (SimpleWebSocketHandler) -> Unit) {
        cleanInvalidHandlers()
        handlers.forEach { action(it.handler) }
    }
    
    // WebSocketMessageListener 接口实现
    override fun onMessageReceived(message: String) {
        val type = parseMessageType(message)
        mainHandler.post {
            notifyHandlers { it.onMessageReceived(type, message) }
        }
    }
    
    override fun onBinaryMessageReceived(bytes: okio.ByteString) {
        // 二进制消息处理（如需使用可扩展）
        Log.i("WebSocketService", "收到二进制消息，长度: ${bytes.size}")
    }
    
    override fun onConnectionOpened() {
        mainHandler.post {
            notifyHandlers { it.onConnectionChanged(true) }
        }
    }
    
    override fun onConnectionClosed(code: Int, reason: String) {
        mainHandler.post {
            notifyHandlers { it.onConnectionChanged(false) }
        }
    }
    
    override fun onConnectionFailed(t: Throwable) {
        mainHandler.post {
            notifyHandlers { it.onError(t.message ?: "连接失败") }
        }
    }
}